package cn.com.b2office.dao.hibernate;

import java.sql.Connection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.com.b2office.bean.AccountStat;
import cn.com.b2office.dao.AccountActivityDao;
import cn.com.b2office.domain.AccountActivity;
import cn.com.b2office.domain.ExData;
import cn.com.b2office.domain.Sequence;
import cn.com.b2office.exchange.ClassMapping;

public class AccountActivityDaoHibernateImpl extends HibernateDaoSupport
		implements AccountActivityDao {

	private static final Log logger = LogFactory
			.getLog(AccountActivityDaoHibernateImpl.class);

	private static final String SEQUENCE_NAME = "ACCOUNT_ACTIVITY";

	private SimpleDateFormat df = new SimpleDateFormat("yyMMdd");

	public void createAccountActivity(AccountActivity activity) {
		if (activity.getActno() == null)
			throw new RuntimeException("ID尚未制定.");
		Session s = getSession();
		try {
			s.save(activity);
			// trigger
			ExData data = new ExData();
			data.setEntity(ClassMapping.getClassCode(AccountActivity.class));
			data.setEntityId(activity.getActno());
			data.setOperation(ExData.INSERT);
			data.setModifytime(new Date());
			s.save(data);
			s.flush();
		} catch (RuntimeException e) {
			throw e;
		} finally {
			releaseSession(s);
		}
	}

	public synchronized String createAccountActivityId() {
		int id = 0;
		Session s = getSession();
		try {
			Sequence sequence = (Sequence) s.get(Sequence.class, SEQUENCE_NAME);
			if (sequence == null) {
				sequence = new Sequence();
				sequence.setName(SEQUENCE_NAME);
				sequence.setNextId(1);
				s.save(sequence);
				s.flush();
			}
			id = sequence.getNextId();
			// 自增
			sequence.setNextId(id + 1);
			s.save(sequence);
			s.flush();
		} catch (RuntimeException e) {
			logger.error(e.getMessage());
			throw e;
		} finally {
			releaseSession(s);
		}
		return "W" + df.format(new Date()) + buildStr(id, 5);
	}

	private String buildStr(int num, int length) {
		String str = String.valueOf(num);
		int strLength = str.length();
		if (strLength >= length)
			return str;
		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < length - strLength; i++) {
			sb.append("0");
		}
		sb.append(str);
		return sb.toString();
	}

	@SuppressWarnings("unchecked")
	public List<AccountActivity> findAccountActivities(String orderId) {
		return getHibernateTemplate().find("from AccountActivity where pono=?",
				orderId);
	}

	public void updateAccountActivity(AccountActivity activity) {
		Session s = getSession();
		try {
			s.update(activity);
			// trigger
			ExData data = new ExData();
			data.setEntity(ClassMapping.getClassCode(AccountActivity.class));
			data.setEntityId(activity.getActno());
			data.setOperation(ExData.UPDATE);
			data.setModifytime(new Date());
			s.save(data);
			s.flush();
		} catch (RuntimeException e) {
			throw e;
		} finally {
			releaseSession(s);
		}
	}

	public AccountStat getAccountStat(String memberId) {
		AccountStat stat = new AccountStat();
		stat.setMemberId(memberId);
		Session s = getSession();
		try {
			String hql = "select sum(amount),sum(getpoint),sum(usepoint) from AccountActivity where status!=-1 and memberid=:memberId";
			Object[] o = (Object[]) s.createQuery(hql).setString("memberId",
					memberId).uniqueResult();
			if (o[0] != null)
				stat.setBalance(((Double) o[0]).floatValue());
			if (o[1] != null)
				stat.setPoints(((Long) o[1]).intValue());
			String hql2 = "select sum(amount) from AccountActivity where status!=-1 and actvtype=2 and memberid=:memberId";
			Object o2 = s.createQuery(hql2).setString("memberId", memberId)
					.uniqueResult();
			if (o2 != null) {
				float sum = ((Double) o2).floatValue();
				stat.setTotalConsume(sum);
			}
		} catch (RuntimeException e) {
			throw e;
		} finally {
			releaseSession(s);
		}
		return stat;
	}
}
